Data transmitted over network connections or retrieved from a storage device, for example, may be corrupted for a variety of reasons. For instance, a noisy transmission line may change a “1” signal to a “0”, or vice versa. To detect corruption, data is often accompanied by some value derived from the data such as a checksum. A receiver of the data can recompute the checksum and compare with the original checksum to confirm that the data was likely transmitted without error.
A common technique to identify data corruption is known as a Cyclic Redundancy Check (CRC). Though not literally a checksum, a CRC value can be used much in the same way. That is, a comparison of an originally computed CRC and a recomputed CRC can identify data corruption with a very high likelihood. CRC computation is based on interpreting message bits as a polynomial, where each bit of the message represents a polynomial coefficient. For example, a message of “1110” corresponds to a polynomial of x3+x2+x+0. The message is divided by another polynomial known as the key. For example, the other polynomial may be “11” or x+1. A CRC is the remainder of a division of the message by the key. CRC polynomial division, however, is somewhat different than ordinary division in that it is computed over the finite field GF(2) (i.e., the set of integers modulo 2). More simply put: even number coefficients become zeroes and odd number coefficients become ones.
A wide variety of techniques have been developed to perform CRC calculations. A first technique uses a dedicated CRC circuit to implement a specific polynomial key. This approach can produce very fast circuitry with a very small footprint. The speed and size, however, often come at the cost of inflexibility with respect to the polynomial key used. Additionally, supporting multiple keys may increase the circuitry footprint nearly linearly for each key supported.
A second commonly used technique features a CRC lookup table where, for a given polynomial and set of data inputs and remainders, all possible CRC results are calculated and stored. Determining a CRC becomes a simple matter of performing table lookups. This approach, however, generally has a comparatively large circuit footprint and may require an entire re-population of the lookup table to change the polynomial key being used.
A third technique is a programmable CRC circuit. This allows nearly any polynomial to be supported in a reasonably efficient amount of die area. Unfortunately, this method can suffer from much slower performance than the previously described methods.